using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;

namespace System
{
    public static class IDictionaryExtentions
    {
        public static IDictionary<TKey, TValue> Initialize<TKey, TValue>(this IDictionary<TKey, TValue> Dictionary,
            int ItemsCount, Func<KeyValuePair<TKey, TValue>> Initializer)
        {
            Contract.Requires(Dictionary != null);
            Contract.Requires(ItemsCount >= 0);
            Contract.Requires(Initializer != null);
            Contract.Ensures(ReferenceEquals(Contract.Result<IDictionary<TKey, TValue>>(), Dictionary));

            for(var i = 0; i < ItemsCount; i++)
                Dictionary.Add(Initializer());

            return Dictionary;
        }

        public static IDictionary<TKey, TValue> Initialize<TKey, TValue>(this IDictionary<TKey, TValue> Dictionary,
            int ItemsCount, Func<int, KeyValuePair<TKey, TValue>> Initializer)
        {
            Contract.Requires(Dictionary != null);
            Contract.Requires(ItemsCount >= 0);
            Contract.Requires(Initializer != null);
            Contract.Ensures(ReferenceEquals(Contract.Result<IDictionary<TKey, TValue>>(), Dictionary));

            for(var i = 0; i < ItemsCount; i++)
                Dictionary.Add(Initializer(i));

            return Dictionary;
        }

        public static IDictionary<TKey, TValue> Initialize<TKey, TValue>(this IDictionary<TKey, TValue> Dictionary,
            IEnumerable<TKey> Keys, Func<TKey, TValue> Initializer)
        {
            Contract.Requires(Dictionary != null);
            Contract.Requires(Keys != null);
            Contract.Requires(Initializer != null);
            Contract.Ensures(ReferenceEquals(Contract.Result<IDictionary<TKey, TValue>>(), Dictionary));

            Keys.Select(key => new KeyValuePair<TKey, TValue>(key, Initializer(key))).Foreach(Dictionary.Add);

            return Dictionary;
        }
    }
}